<!--
  编辑器时间轴组件
  重构后的高性能时间轴
-->
<template>
  <div class="editor-timeline">
    <!-- 时间轴头部 -->
    <div class="timeline-header">
      <div class="timeline-sidebar" :style="{ width: `${sidebarWidth}px` }">
        <div class="timeline-controls">
          <n-button-group size="small">
            <n-button quaternary @click="zoomIn">
              <template #icon>
                <n-icon><AddOutline /></n-icon>
              </template>
            </n-button>
            <n-button quaternary @click="zoomOut">
              <template #icon>
                <n-icon><RemoveOutline /></n-icon>
              </template>
            </n-button>
            <n-button quaternary @click="fitToWindow">
              <template #icon>
                <n-icon><ScanOutline /></n-icon>
              </template>
            </n-button>
          </n-button-group>
        </div>
      </div>
      
      <div class="timeline-ruler" ref="rulerRef">
        <div class="ruler-container" :style="{ minWidth: `${timelineContentWidth}px` }">
          <canvas
            ref="rulerCanvasRef"
            :width="timelineContentWidth"
            :height="30"
            @click="handleRulerClick"
          />
        </div>
      </div>
    </div>
    
    <!-- 时间轴内容 -->
    <div class="timeline-content">
      <div class="timeline-sidebar" :style="{ width: `${sidebarWidth}px`}">
        <n-scrollbar style="height: 100%;" :x-scrollable="false">
          <div class="tracks-sidebar">
            <div
              v-for="track in tracks"
              :key="track.id"
              class="track-header"
              :class="{ selected: isTrackSelected(track.id) }"
              @click="selectTrack(track.id, $event)"
            >
              <div class="track-controls">
                <n-button
                  quaternary
                  size="tiny"
                  @click.stop="toggleTrackVisibility(track.id)"
                >
                  <template #icon>
                    <n-icon>
                      <component :is="track.visible ? EyeOutline : EyeOffOutline" />
                    </n-icon>
                  </template>
                </n-button>

                <n-button
                  quaternary
                  size="tiny"
                  @click.stop="toggleTrackLock(track.id)"
                >
                  <template #icon>
                    <n-icon>
                      <component :is="track.locked ? LockClosedOutline : LockOpenOutline" />
                    </n-icon>
                  </template>
                </n-button>
              </div>

              <div class="track-info">
                <n-icon size="14" :color="getTrackTypeColor(track.type)">
                  <component :is="getTrackTypeIcon(track.type)" />
                </n-icon>
                <span class="track-name">{{ track.name }}</span>
              </div>
            </div>
          </div>
        </n-scrollbar>
      </div>

      <div class="timeline-tracks" ref="tracksRef">
        <div class="tracks-container" :style="{ minWidth: `${timelineContentWidth}px` }">
          <!-- 时间标签已移至Canvas中绘制，避免重复显示 -->

          <!-- 轨道行 -->
          <div
            v-for="(track, index) in tracks"
            :key="track.id"
            class="track-row"
            :class="{
              selected: isTrackSelected(track.id),
              locked: track.locked
            }"
            :style="{
              top: `${index * 40}px`,
              width: `${timelineContentWidth}px`,
              minWidth: `${timelineContentWidth}px`
            }"
            @click="selectTrack(track.id, $event)"
          >
            <!-- 轨道片段 -->
            <div
              v-for="clip in track.clips || []"
              :key="clip.id"
              :data-clip-id="clip.id"
              class="track-clip"
              :class="{
                'locked': track.locked
              }"
              :style="getClipStyle(clip)"
              @mousedown="startDragClipNew(clip, track.id, $event)"
              @click.stop
              :title="`片段: ${clip.name} (${clip.startTime}s - ${clip.endTime}s)`"
            >
              <div class="clip-content">
                <span class="clip-name">{{ clip.name }}</span>
              </div>
              <!-- 拖拽手柄 -->
              <div class="clip-handles" v-if="!track.locked">
                <div class="clip-handle left" @mousedown.stop="startResizeClip(clip, track.id, 'left', $event)"></div>
                <div class="clip-handle right" @mousedown.stop="startResizeClip(clip, track.id, 'right', $event)"></div>
              </div>
            </div>

            <!-- 轨道关键帧 -->
            <div
              v-for="keyframe in track.keyframes"
              :key="keyframe.id"
              class="keyframe"
              :style="{ left: `${keyframe.time * timelineZoom - 6}px` }"
              :class="{ selected: isKeyframeSelected(keyframe.id) }"
              @mousedown="startDragKeyframe(keyframe, $event)"
              @click="selectKeyframe(keyframe.id, $event)"
            >
              <div class="keyframe-diamond" />
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 时间指示器 - 跨越整个时间轴 -->
    <div
      class="time-indicator-full"
      :style="{ left: `${sidebarWidth + timeIndicatorPosition}px` }"
      @mousedown="startDragTimeIndicator"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { NButton, NButtonGroup, NIcon, NScrollbar } from 'naive-ui'
import {
  AddOutline,
  RemoveOutline,
  ScanOutline,
  EyeOutline,
  EyeOffOutline,
  LockClosedOutline,
  LockOpenOutline,
  ImageOutline,
  PersonOutline,
  ImagesOutline,
  SparklesOutline,
  VolumeHighOutline
} from '@vicons/ionicons5'
import { useEditorStore } from '../../stores/editor'
import type { EditorTrack, EditorKeyframe } from '../../stores/editor'
import { useThrottleFn } from '@vueuse/core'
import { useTimelineDrag } from '../../composables/useTimelineDrag'

// 事件定义
const emit = defineEmits(['keyframe-add', 'keyframe-update', 'keyframe-delete', 'time-change', 'clip-update'])

// 状态管理
const editorStore = useEditorStore()

// 拖拽管理器
const { isDragging: dragManagerDragging, hasStarted: dragManagerStarted, startClipDrag } = useTimelineDrag()

// 组件引用
const rulerRef = ref<HTMLElement | null>(null)
const rulerCanvasRef = ref<HTMLCanvasElement | null>(null)
const tracksRef = ref<HTMLElement | null>(null)

// 本地状态
const sidebarWidth = ref(160)
const timelineContainer = ref<HTMLElement | null>(null)
const containerWidth = ref(0)
const playbackControlsWidth = ref(400) // 播放控制器预留宽度

// 滚动同步状态
const scrollSyncHandlers = ref<Array<() => void>>([]) // 存储事件监听器，用于清理

// 片段拖拽状态
const dragClip = ref<any>(null)
const dragClipOriginalTime = ref(0)
const dragAnimationFrame = ref<number | null>(null)
const dragThreshold = 5 // 拖拽阈值，像素
const hasDragStarted = ref(false) // 是否已经开始真正的拖拽
const dragOffset = ref(0) // 鼠标相对于片段左侧的偏移量

// 动态计算轨道高度
const tracksHeight = computed(() => {
  return Math.max(200, tracks.value.length * 40)
})
const isDragging = ref(false)
const dragType = ref<'time-indicator' | 'keyframe' | 'selection' | 'clip' | 'clip-resize-left' | 'clip-resize-right'>('time-indicator')
const dragStartPos = ref({ x: 0, y: 0 })
const dragKeyframe = ref<EditorKeyframe | null>(null)

// 计算属性
const tracks = computed(() => editorStore.tracks)
const currentTime = computed(() => editorStore.playback.currentTime)
const totalDuration = computed(() => editorStore.playback.totalDuration)
const timelineZoom = computed(() => editorStore.timelineZoom)

const timeIndicatorPosition = computed(() => {
  return currentTime.value * timelineZoom.value
})

// 计算时间轴内容宽度 - 基于实际内容，支持自动扩展
const timelineContentWidth = computed(() => {
  // 基于内容的宽度（根据总时长计算）
  const contentBasedWidth = totalDuration.value * timelineZoom.value

  // 计算可用的时间轴宽度（容器宽度减去侧边栏）
  const availableWidth = Math.max(0, containerWidth.value - sidebarWidth.value)

  // 添加适量的额外空间供用户添加内容（相当于额外10秒的空间）
  const extraTime = 10 // 10秒额外空间
  const extraWidth = extraTime * timelineZoom.value

  // 计算最终宽度：内容宽度 + 额外空间，但至少要占满可用宽度
  const finalContentWidth = contentBasedWidth + extraWidth

  // 如果容器宽度为0（还未初始化），则使用内容宽度
  if (containerWidth.value === 0) {
    return finalContentWidth
  }

  // 返回内容宽度和可用宽度中的较大值，确保时间轴能够扩展
  return Math.max(finalContentWidth, availableWidth)
})

const visibleKeyframes = computed(() => {
  const keyframes: Array<EditorKeyframe & { trackId: string; trackIndex: number }> = []

  tracks.value.forEach((track, index) => {
    track.keyframes.forEach(keyframe => {
      keyframes.push({
        ...keyframe,
        trackId: track.id,
        trackIndex: index
      })
    })
  })

  return keyframes
})



// 获取主要间隔 - 强制200px = 10秒的标准
const getMajorInterval = () => {
  // 强制使用10秒间隔，让缩放来适应200px的要求
  // 如果用户想要200px = 10秒，那么timelineZoom应该是20 (200px / 10秒 = 20px/秒)
  return 10
}

// 获取次要间隔 - 确保次刻度间隔合理
const getMinorInterval = () => {
  const majorInterval = getMajorInterval()

  // 根据主要间隔调整次要间隔，目标是每40px左右一个次刻度
  if (majorInterval <= 1) return 0.2      // 每秒主刻度时，每0.2秒一个次刻度
  if (majorInterval <= 5) return 1        // 每5秒主刻度时，每秒一个次刻度
  if (majorInterval <= 10) return 2       // 每10秒主刻度时，每2秒一个次刻度
  if (majorInterval <= 30) return 5       // 每30秒主刻度时，每5秒一个次刻度
  return 10  // 每分钟主刻度时，每10秒一个次刻度
}



// 格式化时间显示
const formatTime = (seconds: number) => {
  const minutes = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  const ms = Math.floor((seconds % 1) * 100)

  if (seconds < 60) {
    // 小于1分钟，显示秒.毫秒
    return `${secs}.${ms.toString().padStart(2, '0')}s`
  } else {
    // 大于1分钟，显示分:秒
    return `${minutes}:${secs.toString().padStart(2, '0')}`
  }
}

// 方法
const isTrackSelected = (trackId: string) => {
  return editorStore.selection.selectedTracks.includes(trackId)
}

const isKeyframeSelected = (keyframeId: string) => {
  return editorStore.selection.selectedKeyframes.includes(keyframeId)
}

const selectTrack = (trackId: string, event: MouseEvent) => {
  event.stopPropagation() // 防止事件冒泡
  event.preventDefault() // 防止默认行为

  const multiSelect = event.ctrlKey || event.metaKey

  // 使用 nextTick 确保在下一个事件循环中执行，避免响应式更新冲突
  nextTick(() => {
    const currentSelection = [...editorStore.selection.selectedTracks]

    if (multiSelect) {
      // 多选模式：切换选择状态
      if (currentSelection.includes(trackId)) {
        // 如果已选中，则取消选择
        editorStore.selection.selectedTracks = currentSelection.filter(id => id !== trackId)
      } else {
        // 如果未选中，则添加到选择列表
        editorStore.selection.selectedTracks = [...currentSelection, trackId]
      }
    } else {
      // 单选模式：切换选择状态
      if (currentSelection.length === 1 && currentSelection[0] === trackId) {
        // 如果当前只选中了这一个轨道，则取消选择
        editorStore.selection.selectedTracks = []
      } else {
        // 否则选中这个轨道
        editorStore.selection.selectedTracks = [trackId]
      }
    }

    editorStore.selection.multiSelect = multiSelect
  })
}

const selectKeyframe = (keyframeId: string, event: MouseEvent) => {
  event.stopPropagation()
  const multiSelect = event.ctrlKey || event.metaKey
  editorStore.selectKeyframe(keyframeId, multiSelect)
}

const toggleTrackVisibility = (trackId: string) => {
  const track = tracks.value.find(t => t.id === trackId)
  if (track) {
    editorStore.updateTrack(trackId, { visible: !track.visible })
  }
}

const toggleTrackLock = (trackId: string) => {
  const track = tracks.value.find(t => t.id === trackId)
  if (track) {
    editorStore.updateTrack(trackId, { locked: !track.locked })
  }
}

const zoomIn = () => {
  editorStore.timelineZoom = Math.min(100, editorStore.timelineZoom * 1.5)
  updateCanvasSize()
}

const zoomOut = () => {
  editorStore.timelineZoom = Math.max(1, editorStore.timelineZoom / 1.5)
  updateCanvasSize()
}

const fitToWindow = () => {
  if (tracksRef.value && totalDuration.value > 0) {
    const availableWidth = tracksRef.value.clientWidth - 20
    editorStore.timelineZoom = availableWidth / totalDuration.value
    updateCanvasSize()
  }
}

const getKeyframeStyle = (keyframe: EditorKeyframe & { trackIndex: number }) => {
  const x = keyframe.time * timelineZoom.value
  const y = keyframe.trackIndex * 40 + 15
  
  return {
    left: `${x - 6}px`,
    top: `${y}px`
  }
}

const getTrackTypeIcon = (type: string) => {
  const icons = {
    image: ImageOutline,
    character: PersonOutline,
    scene: ImagesOutline,
    effect: SparklesOutline,
    audio: VolumeHighOutline
  }
  return icons[type] || ImageOutline
}

const getTrackTypeColor = (type: string) => {
  const colors = {
    image: '#52c41a',
    character: '#ff7875',
    scene: '#13c2c2',
    effect: '#fa8c16',
    audio: '#722ed1'
  }
  return colors[type] || '#8c8c8c'
}

// 获取片段样式 - 使用新的拖拽管理器
const getClipStyle = (clip: any) => {
  // 正常情况下的样式
  return {
    left: `${clip.startTime * timelineZoom.value}px`,
    width: `${(clip.endTime - clip.startTime) * timelineZoom.value}px`
  }
}

// 画布渲染
const drawRuler = () => {
  const canvas = rulerCanvasRef.value
  if (!canvas) return

  const ctx = canvas.getContext('2d')
  if (!ctx) return

  ctx.clearRect(0, 0, canvas.width, canvas.height)

  // 绘制背景 - 根据主题动态调整
  const rootElement = document.documentElement
  const theme = rootElement.getAttribute('data-theme') || 'dark'

  // 根据主题设置背景颜色
  if (theme === 'dark') {
    ctx.fillStyle = '#1e1e1e' // 暗色主题：深灰色
  } else {
    ctx.fillStyle = '#f5f5f5' // 亮色主题：浅灰色
  }
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  // 绘制时间刻度 - 根据主题设置文字颜色
  if (theme === 'dark') {
    ctx.fillStyle = '#cccccc' // 暗色主题：浅灰色文字
  } else {
    ctx.fillStyle = '#666666' // 亮色主题：深灰色文字
  }
  ctx.font = '10px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
  ctx.textAlign = 'center'

  // 使用统一的间隔计算逻辑
  const majorInterval = getMajorInterval()
  const minorInterval = getMinorInterval()

  // 计算时间轴的最大时间范围（基于宽度）
  const maxTimeFromWidth = canvas.width / timelineZoom.value
  const maxTime = Math.max(totalDuration.value, maxTimeFromWidth)

  // 绘制次刻度 - 根据主题设置刻度线颜色
  if (theme === 'dark') {
    ctx.fillStyle = 'rgba(255, 255, 255, 0.1)' // 暗色主题：半透明白色
  } else {
    ctx.fillStyle = 'rgba(0, 0, 0, 0.1)' // 亮色主题：半透明黑色
  }

  for (let time = 0; time <= maxTime; time += minorInterval) {
    const x = time * timelineZoom.value
    if (x > canvas.width) break

    if (time % majorInterval !== 0) {
      // 次刻度线更短更细
      ctx.fillRect(x, 22, 1, 8)
    }
  }

  // 绘制主刻度和时间标签 - 根据主题设置颜色
  if (theme === 'dark') {
    ctx.fillStyle = '#cccccc' // 暗色主题：浅灰色
  } else {
    ctx.fillStyle = '#666666' // 亮色主题：深灰色
  }
  for (let time = 0; time <= maxTime; time += majorInterval) {
    const x = time * timelineZoom.value
    if (x > canvas.width) break

    // 主刻度线 - 更高更明显，使用更强的颜色
    if (theme === 'dark') {
      ctx.fillStyle = 'rgba(255, 255, 255, 0.2)' // 暗色主题：更明显的白色
    } else {
      ctx.fillStyle = 'rgba(0, 0, 0, 0.2)' // 亮色主题：更明显的黑色
    }
    ctx.fillRect(x, 15, 1, 15)

    // 恢复文字颜色
    if (theme === 'dark') {
      ctx.fillStyle = '#cccccc'
    } else {
      ctx.fillStyle = '#666666'
    }

    // 时间标签 - 格式化为分:秒格式
    const minutes = Math.floor(time / 60)
    const seconds = Math.floor(time % 60)
    const timeText = `${minutes}:${seconds.toString().padStart(2, '0')}`

    // 根据位置调整文字对齐方式 - 参考剪映的标签位置
    if (x < 25) {
      // 左边界附近，左对齐
      ctx.textAlign = 'left'
      ctx.fillText(timeText, x + 2, 12)
    } else if (x > canvas.width - 25) {
      // 右边界附近，右对齐
      ctx.textAlign = 'right'
      ctx.fillText(timeText, x - 2, 12)
    } else {
      // 中间区域，居中对齐
      ctx.textAlign = 'center'
      ctx.fillText(timeText, x, 12)
    }
  }
}

// drawTracks 方法已移除，现在使用HTML/CSS实现

// 事件处理
const handleRulerClick = (event: MouseEvent) => {
  const rect = rulerCanvasRef.value?.getBoundingClientRect()
  if (!rect) return
  
  const x = event.clientX - rect.left
  const time = x / timelineZoom.value
  
  editorStore.seekTo(Math.max(0, Math.min(totalDuration.value, time)))
  emit('time-change', time)
}

const startDragTimeIndicator = (event: MouseEvent) => {
  isDragging.value = true
  dragType.value = 'time-indicator'
  dragStartPos.value = { x: event.clientX, y: event.clientY }
  
  document.addEventListener('mousemove', handleDragTimeIndicator)
  document.addEventListener('mouseup', stopDrag)
}

const handleDragTimeIndicator = useThrottleFn((event: MouseEvent) => {
  if (!isDragging.value || dragType.value !== 'time-indicator') return
  
  const rect = rulerCanvasRef.value?.getBoundingClientRect()
  if (!rect) return
  
  const x = event.clientX - rect.left
  const time = Math.max(0, Math.min(totalDuration.value, x / timelineZoom.value))
  
  editorStore.seekTo(time)
  emit('time-change', time)
}, 16)

const startDragKeyframe = (keyframe: EditorKeyframe, event: MouseEvent) => {
  event.stopPropagation()

  isDragging.value = true
  dragType.value = 'keyframe'
  dragKeyframe.value = keyframe
  dragStartPos.value = { x: event.clientX, y: event.clientY }

  document.addEventListener('mousemove', handleDragKeyframe)
  document.addEventListener('mouseup', stopDrag)
}

// 新的片段拖拽功能 - 使用拖拽管理器
const startDragClipNew = (clip: any, trackId: string, event: MouseEvent) => {
  console.log('🎬 [Timeline] 开始新的拖拽系统:', {
    clipId: clip.id,
    clipName: clip.name,
    trackId
  })

  // 获取片段元素
  const clipElement = event.target as HTMLElement

  // 配置拖拽管理器
  const dragConfig = {
    threshold: 5,
    timelineZoom: timelineZoom.value,
    containerElement: tracksRef.value,
    onUpdate: (data: any) => {
      // 拖拽过程中的实时更新（可选）
      console.log('🔄 [Timeline] 拖拽更新:', data)
    },
    onComplete: (data: any) => {
      // 拖拽完成，提交更改
      console.log('✅ [Timeline] 拖拽完成，提交更改:', data)

      // 更新编辑器状态
      const track = tracks.value.find(t => t.id === data.trackId)
      if (track) {
        const clipIndex = track.clips?.findIndex(c => c.id === data.clipId)
        if (clipIndex !== undefined && clipIndex >= 0 && track.clips) {
          // 更新片段位置
          track.clips[clipIndex].startTime = data.startTime
          track.clips[clipIndex].endTime = data.endTime

          // 更新总时长
          const maxEndTime = Math.max(...tracks.value.flatMap(t => t.clips?.map(c => c.endTime) || []))
          editorStore.playback.totalDuration = Math.max(editorStore.playback.totalDuration, maxEndTime)

          console.log('📊 [Timeline] 更新完成，新的总时长:', editorStore.playback.totalDuration)
        }
      }
    },
    onCancel: () => {
      console.log('❌ [Timeline] 拖拽取消')
    }
  }

  // 启动拖拽
  startClipDrag(clip, trackId, clipElement, event, dragConfig)
}

// 片段缩放功能
const startResizeClip = (clip: any, trackId: string, handle: 'left' | 'right', event: MouseEvent) => {
  event.stopPropagation()

  isDragging.value = true
  dragType.value = handle === 'left' ? 'clip-resize-left' : 'clip-resize-right'
  dragClip.value = { ...clip, trackId }
  dragClipOriginalTime.value = clip.startTime
  dragStartPos.value = { x: event.clientX, y: event.clientY }

  // 添加视觉反馈
  const clipElement = document.querySelector(`[data-clip-id="${clip.id}"]`) as HTMLElement
  if (clipElement) {
    clipElement.classList.add('resizing')
  }

  document.addEventListener('mousemove', handleResizeClip)
  document.addEventListener('mouseup', stopDrag)
}

const handleDragKeyframe = useThrottleFn((event: MouseEvent) => {
  if (!isDragging.value || dragType.value !== 'keyframe' || !dragKeyframe.value) return

  const rect = tracksRef.value?.getBoundingClientRect()
  if (!rect) return

  const x = event.clientX - rect.left
  const newTime = Math.max(0, Math.min(totalDuration.value, x / timelineZoom.value))

  // 找到包含该关键帧的轨道
  for (const track of tracks.value) {
    const keyframeIndex = track.keyframes.findIndex(kf => kf.id === dragKeyframe.value!.id)
    if (keyframeIndex !== -1) {
      emit('keyframe-update', track.id, dragKeyframe.value.id, { time: newTime })
      break
    }
  }
}, 16)

// 片段拖拽处理 - 添加拖拽阈值，防止意外拖拽
const handleDragClip = (event: MouseEvent) => {
  if (!isDragging.value || dragType.value !== 'clip' || !dragClip.value) {
    console.log('❌ 拖拽条件不满足:', {
      isDragging: isDragging.value,
      dragType: dragType.value,
      hasDragClip: !!dragClip.value
    })
    return
  }

  // 计算鼠标移动距离
  const deltaX = Math.abs(event.clientX - dragStartPos.value.x)
  const deltaY = Math.abs(event.clientY - dragStartPos.value.y)
  const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)

  // 如果移动距离小于阈值，不开始拖拽
  if (!hasDragStarted.value && distance < dragThreshold) {
    console.log('📏 移动距离未达到阈值:', { distance, threshold: dragThreshold })
    return
  }

  // 第一次超过阈值，开始真正的拖拽
  if (!hasDragStarted.value) {
    console.log('🚀 开始真正的拖拽 - 超过阈值')
    hasDragStarted.value = true
    // 添加拖拽样式
    const clipElement = document.querySelector(`[data-clip-id="${dragClip.value.id}"]`) as HTMLElement
    if (clipElement) {
      clipElement.classList.add('dragging')
      console.log('✅ 添加拖拽样式')
    }
  }

  // 取消之前的动画帧
  if (dragAnimationFrame.value) {
    cancelAnimationFrame(dragAnimationFrame.value)
  }

  // 使用 requestAnimationFrame 确保流畅的动画
  dragAnimationFrame.value = requestAnimationFrame(() => {
    const rect = tracksRef.value?.getBoundingClientRect()
    if (!rect) {
      console.log('❌ 无法获取轨道容器边界 - 拖拽过程中')
      return
    }

    // 计算鼠标当前位置相对于轨道容器的位置
    const mouseX = event.clientX - rect.left

    // 减去初始偏移量，得到片段左侧应该在的位置
    const clipLeftPosition = mouseX - dragOffset.value
    const newStartTime = Math.max(0, clipLeftPosition / timelineZoom.value)
    const clipDuration = dragClip.value.endTime - dragClip.value.startTime
    const newEndTime = newStartTime + clipDuration

    console.log('🎯 拖拽位置计算:', {
      mouseX,
      dragOffset: dragOffset.value,
      clipLeftPosition,
      newStartTime,
      originalTime: dragClipOriginalTime.value,
      duration: clipDuration
    })

    // 只更新临时拖拽数据，用于最终的重叠检测
    dragClip.value.startTime = newStartTime
    dragClip.value.endTime = newEndTime

    // 使用 transform 来移动片段，避免与数据绑定冲突
    const clipElement = document.querySelector(`[data-clip-id="${dragClip.value.id}"]`) as HTMLElement
    if (clipElement) {
      const translateX = newStartTime * timelineZoom.value - (dragClipOriginalTime.value * timelineZoom.value)
      console.log('🔄 应用 transform:', { translateX })
      clipElement.style.transform = `translateX(${translateX}px)`
    } else {
      console.log('❌ 找不到片段元素:', dragClip.value.id)
    }
  })
}

// 片段缩放处理 - 直接更新数据，无节流
const handleResizeClip = (event: MouseEvent) => {
  if (!isDragging.value || (!dragType.value.startsWith('clip-resize')) || !dragClip.value) return

  const rect = tracksRef.value?.getBoundingClientRect()
  if (!rect) return

  const x = event.clientX - rect.left
  const newTime = Math.max(0, x / timelineZoom.value)

  const track = tracks.value.find(t => t.id === dragClip.value.trackId)
  if (!track || !track.clips) return

  const otherClips = track.clips.filter(c => c.id !== dragClip.value.id)
  let newStartTime = dragClip.value.startTime
  let newEndTime = dragClip.value.endTime

  if (dragType.value === 'clip-resize-left') {
    newStartTime = Math.min(newTime, dragClip.value.endTime - 0.1) // 最小0.1秒
    // 检查左侧是否与其他片段重叠
    const hasOverlap = otherClips.some(clip =>
      newStartTime < clip.endTime && clip.endTime <= dragClip.value.endTime
    )
    if (!hasOverlap) {
      newStartTime = Math.max(0, newStartTime)
    } else {
      return // 有重叠，不更新
    }
  } else if (dragType.value === 'clip-resize-right') {
    newEndTime = Math.max(newTime, dragClip.value.startTime + 0.1) // 最小0.1秒
    // 检查右侧是否与其他片段重叠
    const hasOverlap = otherClips.some(clip =>
      newEndTime > clip.startTime && clip.startTime >= dragClip.value.startTime
    )
    if (!hasOverlap) {
      newEndTime = newEndTime
    } else {
      return // 有重叠，不更新
    }
  }

  // 直接更新片段数据，实现实时跟随
  emit('clip-update', dragClip.value.trackId, dragClip.value.id, {
    startTime: newStartTime,
    endTime: newEndTime
  })
}

// 轨道相关的事件处理现在直接在HTML模板中处理

const stopDrag = () => {
  console.log('🛑 停止拖拽')

  // 清理动画帧
  if (dragAnimationFrame.value) {
    cancelAnimationFrame(dragAnimationFrame.value)
    dragAnimationFrame.value = null
    console.log('🧹 清理动画帧')
  }

  // 如果是片段缩放，清理样式
  if ((dragType.value === 'clip-resize-left' || dragType.value === 'clip-resize-right') && dragClip.value) {
    const clipElement = document.querySelector(`[data-clip-id="${dragClip.value.id}"]`) as HTMLElement
    if (clipElement) {
      clipElement.classList.remove('resizing')
    }
  }

  // 如果是片段拖拽，进行最终的重叠检测和数据同步
  if (dragType.value === 'clip' && dragClip.value) {
    console.log('🎬 处理片段拖拽结束:', {
      clipId: dragClip.value.id,
      hasDragStarted: hasDragStarted.value,
      finalStartTime: dragClip.value.startTime,
      finalEndTime: dragClip.value.endTime,
      originalTime: dragClipOriginalTime.value
    })

    const clipElement = document.querySelector(`[data-clip-id="${dragClip.value.id}"]`) as HTMLElement

    // 重置视觉样式
    if (clipElement) {
      console.log('🔄 重置片段样式')
      clipElement.style.transform = ''
      clipElement.classList.remove('dragging')
    } else {
      console.log('❌ 找不到要重置的片段元素')
    }

    // 只有在真正开始拖拽后才进行位置更新
    if (hasDragStarted.value) {
      console.log('✅ 真正拖拽过，进行重叠检测')
      const track = tracks.value.find(t => t.id === dragClip.value.trackId)
      if (track && track.clips) {
        const otherClips = track.clips.filter(c => c.id !== dragClip.value.id)
        const hasOverlap = otherClips.some(clip =>
          (dragClip.value.startTime < clip.endTime && dragClip.value.endTime > clip.startTime)
        )

        console.log('🔍 重叠检测结果:', {
          hasOverlap,
          otherClipsCount: otherClips.length,
          startTimeValid: dragClip.value.startTime >= 0,
          endTime: dragClip.value.endTime,
          currentTotalDuration: totalDuration.value
        })

        // 只检查左边界（不能小于0）和重叠，不限制右边界（时间轴可以自动扩展）
        if (!hasOverlap && dragClip.value.startTime >= 0) {
          // 没有重叠且不超出左边界，提交更改到实际数据
          console.log('✅ 提交片段位置更新 - 时间轴将自动扩展')
          emit('clip-update', dragClip.value.trackId, dragClip.value.id, {
            startTime: dragClip.value.startTime,
            endTime: dragClip.value.endTime
          })
        } else {
          console.log('❌ 有重叠或超出左边界，不提交更新', {
            hasOverlap,
            startTimeValid: dragClip.value.startTime >= 0
          })
        }
        // 如果有重叠或超出边界，transform重置后片段会自动回到原位
      } else {
        console.log('❌ 找不到轨道或轨道没有片段')
      }
    } else {
      console.log('ℹ️ 没有真正拖拽，只是点击')
    }
  }

  console.log('🧹 清理拖拽状态')
  isDragging.value = false
  dragKeyframe.value = null
  dragClip.value = null
  hasDragStarted.value = false
  dragOffset.value = 0

  document.removeEventListener('mousemove', handleDragTimeIndicator)
  document.removeEventListener('mousemove', handleDragKeyframe)
  document.removeEventListener('mousemove', handleDragClip)
  document.removeEventListener('mousemove', handleResizeClip)
  document.removeEventListener('mouseup', stopDrag)

  console.log('✅ 拖拽完全结束')
}

// 更新画布尺寸
const updateCanvasSize = () => {
  nextTick(() => {
    if (rulerRef.value && tracksRef.value) {
      // tracksHeight现在是计算属性，会自动更新

      // 重新绘制
      drawRuler()
    }
  })
}

// 生命周期
onMounted(() => {
  updateCanvasSize()
  updateContainerWidth()

  // 设置滚动同步
  setupScrollSync()
})

onBeforeUnmount(() => {
  stopDrag()
  cleanupScrollSync() // 清理滚动同步事件监听器
})

// 监听变化
watch([tracks, timelineZoom, totalDuration], updateCanvasSize)
watch(currentTime, drawRuler)
watch(timelineContentWidth, () => {
  // 当时间轴内容宽度变化时，重新设置滚动同步
  nextTick(() => {
    setupScrollSync()
  })
})

// 监听容器宽度变化
const updateContainerWidth = () => {
  // 获取时间轴容器的实际宽度
  const timelineElement = rulerRef.value?.parentElement
  if (timelineElement) {
    containerWidth.value = timelineElement.clientWidth
  }
}

// 设置滚动同步
const setupScrollSync = () => {
  const rulerElement = rulerRef.value
  const tracksElement = tracksRef.value

  if (!rulerElement || !tracksElement) {
    console.warn('滚动同步：无法找到标尺或轨道元素')
    return
  }

  // 清理之前的事件监听器
  cleanupScrollSync()

  let isScrolling = false // 防止循环触发

  const syncScroll = (source: HTMLElement, target: HTMLElement, direction: string) => {
    if (isScrolling) return
    isScrolling = true

    console.log(`滚动同步：${direction} -> scrollLeft: ${source.scrollLeft}`)
    target.scrollLeft = source.scrollLeft

    // 使用 requestAnimationFrame 确保滚动完成后再重置标志
    requestAnimationFrame(() => {
      isScrolling = false
    })
  }

  // 创建事件处理器
  const rulerScrollHandler = () => syncScroll(rulerElement, tracksElement, '标尺->轨道')
  const tracksScrollHandler = () => syncScroll(tracksElement, rulerElement, '轨道->标尺')

  // 添加事件监听器
  rulerElement.addEventListener('scroll', rulerScrollHandler, { passive: true })
  tracksElement.addEventListener('scroll', tracksScrollHandler, { passive: true })

  // 存储清理函数
  scrollSyncHandlers.value = [
    () => rulerElement.removeEventListener('scroll', rulerScrollHandler),
    () => tracksElement.removeEventListener('scroll', tracksScrollHandler)
  ]

  console.log('滚动同步已设置')
}

// 清理滚动同步
const cleanupScrollSync = () => {
  scrollSyncHandlers.value.forEach(cleanup => cleanup())
  scrollSyncHandlers.value = []
}

// 监听窗口大小变化，重新计算时间轴宽度
const resizeObserver = new ResizeObserver(() => {
  nextTick(() => {
    // 更新容器宽度
    updateContainerWidth()
    // 触发timelineContentWidth重新计算
    updateCanvasSize()
  })
})

// 监听主题变化，重新绘制Canvas
const themeObserver = new MutationObserver(() => {
  nextTick(() => {
    drawRuler()
  })
})

onMounted(() => {
  // 监听主题变化
  themeObserver.observe(document.documentElement, {
    attributes: true,
    attributeFilter: ['class', 'data-theme']
  })

  // 监听时间轴容器大小变化
  nextTick(() => {
    if (tracksRef.value) {
      resizeObserver.observe(tracksRef.value)
    }
  })
})

onBeforeUnmount(() => {
  themeObserver.disconnect()
  resizeObserver.disconnect()
})
</script>

<style lang="scss" scoped>
.editor-timeline {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--card-color);
  border-top: 1px solid var(--border-color);
}

.timeline-header {
  display: flex;
  height: 30px;
  border-bottom: 1px solid var(--border-color);
}

.timeline-sidebar {
  background: var(--body-color);
  border-right: 1px solid var(--border-color);
  flex-shrink: 0;
}

.timeline-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0 8px;
}

.timeline-ruler {
  position: relative;
  flex: 1;
  overflow-x: auto; /* 启用水平滚动 */
  overflow-y: hidden;
  background: var(--body-color);
  border-bottom: 1px solid var(--border-color);

  .ruler-container {
    position: relative;
    width: max-content; /* 让容器根据内容宽度自适应 */
    min-width: 100%; /* 至少占满可用宽度 */
    height: 100%;

    canvas {
      display: block;
      cursor: pointer;
      background: var(--body-color);
    }
  }
}

.time-indicator {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--primary-color);
  cursor: ew-resize;
  z-index: 10;

  &::before {
    content: '';
    position: absolute;
    top: -5px;
    left: -5px;
    width: 12px;
    height: 12px;
    background: var(--primary-color);
    border-radius: 50%;
  }
}

.time-indicator-full {
  position: absolute;
  top: 0; /* 从时间轴顶部开始 */
  bottom: 0;
  width: 2px;
  background: var(--primary-color);
  cursor: ew-resize;
  z-index: 50; /* 在时间轴内容之上，但低于播放控制器 */
  pointer-events: auto;

  &::before {
    content: '';
    position: absolute;
    left: -5px;
    width: 12px;
    height: 12px;
    background: var(--primary-color);
    border-radius: 50%;
    border: 2px solid white;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  }

  &:hover::before {
    transform: scale(1.2);
    transition: transform 0.2s ease;
  }
}

.timeline-content {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.tracks-sidebar {
  height: 100%;
}

.track-header {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 8px;
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
  transition: background-color 0.2s ease;
  
  &:hover {
    background: var(--hover-color);
  }
  
  &.selected {
    background: var(--primary-color-pressed) !important;
    color: white !important;
  }
  
  .track-controls {
    display: flex;
    gap: 4px;
    margin-right: 8px;
  }
  
  .track-info {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
    min-width: 0;
    
    .track-name {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      font-size: 12px;
    }
  }
}

.timeline-tracks {
  position: relative;
  flex: 1;
  overflow-x: auto; /* 启用水平滚动 */
  overflow-y: hidden; /* 移除垂直滚动条 */

  .tracks-container {
    overflow-y: auto;
    position: relative;
    width: max-content; /* 让容器根据内容宽度自适应 */
    min-width: 100%; /* 至少占满可用宽度 */
    height: 100%;
  }



  /* 时间标签样式已移除，现在在Canvas中绘制 */

  .track-row {
    position: absolute;
    left: 0;
    width: 100%;
    min-width: 100%; /* 确保轨道行至少占满容器宽度 */
    height: 40px;
    border-bottom: 1px solid var(--border-color);
    background-color: var(--card-color);
    cursor: pointer;
    transition: background-color 0.2s ease;

    &:nth-child(even) {
      background-color: var(--body-color);
    }

    &:hover {
      background-color: var(--hover-color);
    }

    &.selected {
      background-color: var(--primary-color-pressed);
      border-color: var(--primary-color);
    }

    &.locked {
      opacity: 0.6;
      cursor: not-allowed;
    }
  }

  .track-clip {
    position: absolute;
    top: 4px;
    height: 32px;
    background: linear-gradient(135deg, #10b981, #059669);
    border-radius: 4px;
    border: 1px solid #10b981;
    cursor: move;
    overflow: hidden;
    transition: all 0.2s ease;
    user-select: none;
    z-index: 2; /* 片段在网格线下方，但高于轨道背景 */

    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);

      .clip-handles {
        opacity: 1;
      }
    }

    &.dragging {
      z-index: 100;
      opacity: 0.9;
      transform: translateY(-2px);
      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
      transition: none; /* 拖拽时禁用过渡动画 */
      will-change: transform; /* 优化GPU加速 */
    }

    &.resizing {
      z-index: 100;
      transition: none; /* 缩放时禁用过渡动画 */
      will-change: transform; /* 优化GPU加速 */

      .clip-handles {
        opacity: 1;

        .clip-handle {
          background: rgba(255, 255, 255, 0.8);
        }
      }
    }

    &.locked {
      cursor: not-allowed;
      opacity: 0.6;
    }

    .clip-content {
      padding: 4px 8px;
      height: 100%;
      display: flex;
      align-items: center;
      pointer-events: none; /* 防止文字阻止拖拽 */

      .clip-name {
        color: white;
        font-size: 12px;
        font-weight: 500;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }

    .clip-handles {
      opacity: 0;
      transition: opacity 0.2s ease;

      .clip-handle {
        position: absolute;
        top: 0;
        width: 6px;
        height: 100%;
        background: rgba(255, 255, 255, 0.3);
        cursor: ew-resize;
        transition: background 0.2s ease;

        &:hover {
          background: rgba(255, 255, 255, 0.6);
        }

        &.left {
          left: 0;
          border-top-left-radius: 4px;
          border-bottom-left-radius: 4px;
        }

        &.right {
          right: 0;
          border-top-right-radius: 4px;
          border-bottom-right-radius: 4px;
        }
      }
    }
  }

  .keyframe {
    position: absolute;
    top: 15px;
    width: 12px;
    height: 12px;
    cursor: pointer;
    z-index: 10;
    transition: all 0.2s ease;

    &:hover {
      transform: scale(1.2);
    }

    &.selected {
      transform: scale(1.3);
    }

    .keyframe-diamond {
      width: 100%;
      height: 100%;
      background: var(--warning-color);
      border: 2px solid white;
      border-radius: 2px;
      transform: rotate(45deg);
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    }
  }
}

/* 暗色主题特定样式 */
[data-theme='dark'] .editor-timeline {
  background: #1a1a1a; /* 更深的背景 */
  border-top-color: rgba(255, 255, 255, 0.08);

  .timeline-sidebar {
    background: #1e1e1e; /* 侧边栏稍微亮一点 */
    border-right-color: rgba(255, 255, 255, 0.08);
  }

  .track-header {
    &.selected {
      background: rgba(24, 144, 255, 0.15) !important; /* 与右侧轨道行保持一致 */
      color: white !important;
    }
  }

  .timeline-ruler {
    background: #1e1e1e; /* 标尺区域 */
    border-bottom-color: rgba(255, 255, 255, 0.08);

    canvas {
      background: #1e1e1e;
    }
  }

  .timeline-tracks {
    .tracks-container {

      .track-row {
        background-color: #1a1a1a;
        border-bottom-color: rgba(255, 255, 255, 0.06);

        &:nth-child(even) {
          background-color: #1e1e1e;
        }

        &:hover {
          background-color: rgba(255, 255, 255, 0.04);
        }

        &.selected {
          background-color: rgba(24, 144, 255, 0.15);
          border-color: #1890ff;
        }
      }
    }
  }
}

/* 亮色主题特定样式 */
[data-theme='light'] .editor-timeline {
  background: #fafafa; /* 更浅的背景 */
  border-top-color: rgba(0, 0, 0, 0.06);

  .timeline-sidebar {
    background: #f5f5f5; /* 侧边栏稍微深一点 */
    border-right-color: rgba(0, 0, 0, 0.06);
  }

  .track-header {
    &.selected {
      background: rgba(24, 144, 255, 0.08) !important; /* 与右侧轨道行保持一致 */
      color: white !important;
    }
  }

  .timeline-ruler {
    background: #f5f5f5; /* 标尺区域 */
    border-bottom-color: rgba(0, 0, 0, 0.06);

    canvas {
      background: #f5f5f5;
    }
  }

  .timeline-tracks {
    .tracks-container {

      .track-row {
        background-color: #fafafa;
        border-bottom-color: rgba(0, 0, 0, 0.06);

        &:nth-child(even) {
          background-color: #f5f5f5;
        }

        &:hover {
          background-color: rgba(0, 0, 0, 0.02);
        }

        &.selected {
          background-color: rgba(24, 144, 255, 0.08);
          border-color: #1890ff;
        }
      }
    }
  }
}
</style>
